﻿using System;
using System.Reflection;
using System.ServiceModel.Channels;
using System.Threading.Tasks;
using System.Transactions;
using RockBus.Logging.Interfaces;
using RockBus.Transport.Interfaces;

namespace RockBus.Transport.Wcf
{
    public class TransportTwoWay : ITransport
    {
        public TransportTwoWay(ILogger logger, ITwoWay client, MessageVersion messageVersion)
        {
            Logger = logger;
            Client = client;
            MessageVersion = messageVersion;
        }

        private ILogger Logger { get; set; }

        private ITwoWay Client { get; set; }

        public MessageVersion MessageVersion { get; private set; }

        public Task<Message> StartTransportMessage(Message message)
        {
            var cc = new CallContext<ITwoWay>
            {
                Client = ((TwoWayClient) Client).Contract,
            };

            Logger.LogDebug(MethodBase.GetCurrentMethod(), "Transporting message with action {0}",
                message.Headers.Action);
            Logger.Log(MethodBase.GetCurrentMethod(), LogLevelEnum.Debug, Transaction.Current);

            Task<Message> task = Task<Message>.Factory.FromAsync(
                Client.BeginProcessRequest,
                EndProcessRequest,
                message,
                cc,
                TaskCreationOptions.AttachedToParent);
            return task;
        }

        private Message EndProcessRequest(IAsyncResult asyncResult)
        {
            Logger.Log(MethodBase.GetCurrentMethod(), LogLevelEnum.Debug, Transaction.Current);

            Message result = null;
            try
            {
                var cc = asyncResult.AsyncState as CallContext<ITwoWay>;
                result = cc.Client.EndProcessRequest(asyncResult);
            }
            catch (Exception exc)
            {
                Logger.LogError(MethodBase.GetCurrentMethod(), exc.ToString());
                throw;
            }

            return result;
        }
    }
}